from PyQt6.QtWidgets import (QWidget, QVBoxLayout, QPushButton, 
                           QLabel, QFileDialog, QProgressBar,
                           QListWidget, QHBoxLayout, QSpacerItem,
                           QSizePolicy, QMessageBox, QMenu, QListWidgetItem,
                           QFrame)
from PyQt6.QtCore import Qt, QTimer, pyqtSignal, QObject
from PyQt6.QtGui import QFont, QIcon, QAction
from utils.converter import FileConverter
import os
import threading

# 创建一个信号发射器类
class SignalEmitter(QObject):
    progress_signal = pyqtSignal(int)
    error_signal = pyqtSignal(str)
    complete_signal = pyqtSignal()

class PDFConverterWidget(QWidget):
    # 定义支持的文件类型
    SUPPORTED_FORMATS = {
        'Word文档': ['.doc', '.docx'],
        'Excel表格': ['.xls', '.xlsx'],
        'PowerPoint': ['.ppt', '.pptx'],
        '图片文件': ['.jpg', '.jpeg', '.png', '.gif', '.bmp'],
        'PDF文件': ['.pdf']
    }
    
    def __init__(self, title="PDF文件转换", description="将文件转换为PDF格式"):
        super().__init__()
        self.title = title
        self.description = description
        self.selected_files = []
        self.save_path = ""
        
        # 创建信号发射器
        self.signal_emitter = SignalEmitter()
        self.signal_emitter.progress_signal.connect(self.on_progress_update)
        self.signal_emitter.error_signal.connect(self.on_error)
        self.signal_emitter.complete_signal.connect(self.on_conversion_complete)
        
        self.init_ui()
        
    def init_ui(self):
        layout = QVBoxLayout(self)
        layout.setContentsMargins(20, 20, 20, 20)
        
        # 添加说明标签
        title = QLabel(self.title)
        title.setFont(QFont("Arial", 16, QFont.Weight.Bold))
        layout.addWidget(title)
        
        # 添加操作说明
        desc = QLabel(self.description)
        desc.setStyleSheet("color: #666666;")
        layout.addWidget(desc)
        
        # 添加步骤提示
        step1 = QLabel("1. 选择需要转换的文件")
        step1.setFont(QFont("Arial", 11))
        layout.addWidget(step1)
        
        # 添加支持格式说明
        format_info = QLabel("支持的文件格式：")
        format_info.setFont(QFont("Arial", 10))
        layout.addWidget(format_info)
        
        # 添加格式列表
        format_list = QVBoxLayout()
        format_list.setSpacing(5)
        for category, extensions in self.SUPPORTED_FORMATS.items():
            format_text = QLabel(f"• {category}：{', '.join(extensions)}")
            format_text.setStyleSheet("color: #666666; margin-left: 20px;")
            format_list.addWidget(format_text)
        layout.addLayout(format_list)
        
        # 添加分隔线
        separator = QFrame()
        separator.setFrameShape(QFrame.Shape.HLine)
        separator.setFrameShadow(QFrame.Shadow.Sunken)
        separator.setStyleSheet("background-color: #CCCCCC;")
        layout.addWidget(separator)
        
        # 文件选择区域
        select_area = QHBoxLayout()
        self.select_btn = QPushButton("选择文件")
        self.select_btn.setMinimumWidth(120)
        self.select_btn.setStyleSheet("""
            QPushButton {
                background-color: #2B579A;
                color: white;
                padding: 8px 16px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #1E3F7F;
            }
        """)
        self.select_btn.clicked.connect(self.select_files)
        select_area.addWidget(self.select_btn)
        
        self.file_count_label = QLabel("未选择文件")
        self.file_count_label.setStyleSheet("color: #666666;")
        select_area.addWidget(self.file_count_label)
        select_area.addStretch()
        layout.addLayout(select_area)
        
        # 文件列表
        step2 = QLabel("2. 已选择的文件")
        step2.setFont(QFont("Arial", 11))
        layout.addWidget(step2)
        
        # 文件列表区域
        file_list_area = QVBoxLayout()
        
        # 添加文件列表
        self.file_list = QListWidget()
        self.file_list.setStyleSheet("""
            QListWidget {
                border: 1px solid #CCCCCC;
                border-radius: 4px;
                padding: 5px;
            }
            QListWidget::item {
                padding: 5px;
                border-bottom: 1px solid #EEEEEE;
                margin: 2px 0;
            }
            QListWidget::item:hover {
                background: #f0f0f0;
            }
            QListWidget::item:selected {
                background: #e0e0e0;
                color: black;
            }
        """)
        self.file_list.setMinimumHeight(200)
        self.file_list.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.file_list.customContextMenuRequested.connect(self.show_context_menu)
        file_list_area.addWidget(self.file_list)
        
        # 添加文件操作按钮
        file_actions = QHBoxLayout()
        
        self.clear_btn = QPushButton("清空列表")
        self.clear_btn.setStyleSheet("""
            QPushButton {
                background-color: #dc3545;
                color: white;
                padding: 5px 10px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #c82333;
            }
            QPushButton:disabled {
                background-color: #CCCCCC;
            }
        """)
        self.clear_btn.clicked.connect(self.clear_file_list)
        file_actions.addWidget(self.clear_btn)
        
        self.remove_btn = QPushButton("删除选中")
        self.remove_btn.setStyleSheet("""
            QPushButton {
                background-color: #ffc107;
                color: black;
                padding: 5px 10px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #e0a800;
            }
            QPushButton:disabled {
                background-color: #CCCCCC;
            }
        """)
        self.remove_btn.clicked.connect(self.remove_selected_files)
        file_actions.addWidget(self.remove_btn)
        
        file_actions.addStretch()
        file_list_area.addLayout(file_actions)
        layout.addLayout(file_list_area)
        
        # 添加保存路径选择
        step3 = QLabel("3. 选择保存位置")
        step3.setFont(QFont("Arial", 11))
        layout.addWidget(step3)
        
        save_area = QHBoxLayout()
        self.save_path_label = QLabel("未选择保存位置")
        self.save_path_label.setStyleSheet("color: #666666;")
        save_area.addWidget(self.save_path_label)
        
        self.save_btn = QPushButton("选择路径")
        self.save_btn.setStyleSheet("""
            QPushButton {
                background-color: #2B579A;
                color: white;
                padding: 8px 16px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #1E3F7F;
            }
        """)
        self.save_btn.clicked.connect(self.select_save_path)
        save_area.addWidget(self.save_btn)
        layout.addLayout(save_area)
        
        # 转换进度
        step4 = QLabel("4. 转换进度")
        step4.setFont(QFont("Arial", 11))
        layout.addWidget(step4)
        
        self.progress_bar = QProgressBar()
        self.progress_bar.setStyleSheet("""
            QProgressBar {
                border: 1px solid #CCCCCC;
                border-radius: 4px;
                text-align: center;
            }
            QProgressBar::chunk {
                background-color: #2B579A;
            }
        """)
        self.progress_bar.hide()
        layout.addWidget(self.progress_bar)
        
        # 转换按钮
        convert_area = QHBoxLayout()
        convert_area.addStretch()
        self.convert_btn = QPushButton("开始转换")
        self.convert_btn.setMinimumWidth(120)
        self.convert_btn.setStyleSheet("""
            QPushButton {
                background-color: #2B579A;
                color: white;
                padding: 8px 16px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #1E3F7F;
            }
            QPushButton:disabled {
                background-color: #CCCCCC;
            }
        """)
        self.convert_btn.clicked.connect(self.start_conversion)
        self.convert_btn.setEnabled(False)
        convert_area.addWidget(self.convert_btn)
        layout.addLayout(convert_area)
        
        # 添加状态标签
        self.status_label = QLabel("")
        self.status_label.setStyleSheet("color: #666666;")
        self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
        layout.addWidget(self.status_label)
        
        layout.addStretch()
        
    def select_save_path(self):
        path = QFileDialog.getExistingDirectory(
            self,
            "选择保存位置",
            "",
            QFileDialog.Option.ShowDirsOnly
        )
        if path:
            self.save_path = path
            self.save_path_label.setText(f"保存位置: {path}")
            self.update_convert_button()
            
    def select_files(self):
        # 构建文件过滤器
        filters = []
        all_supported = []
        
        # 为每种类型创建过滤器
        for category, extensions in self.SUPPORTED_FORMATS.items():
            ext_filters = [f"*{ext}" for ext in extensions]
            all_supported.extend(ext_filters)
            filters.append(f"{category} ({' '.join(ext_filters)})")
        
        # 添加"所有支持的格式"选项
        filters.insert(0, f"所有支持的格式 ({' '.join(all_supported)})")
        
        files, _ = QFileDialog.getOpenFileNames(
            self,
            "选择要转换的文件",
            "",
            ";;".join(filters)
        )
        
        if files:
            # 验证文件格式
            valid_files = []
            invalid_files = []
            
            for file in files:
                ext = os.path.splitext(file)[1].lower()
                is_valid = any(ext in exts for exts in self.SUPPORTED_FORMATS.values())
                
                if is_valid and file not in self.selected_files:
                    valid_files.append(file)
                elif not is_valid:
                    invalid_files.append(os.path.basename(file))
            
            # 如果有无效文件，显示警告
            if invalid_files:
                QMessageBox.warning(
                    self,
                    "不支持的文件格式",
                    f"以下文件格式不受支持，已被忽略：\n{', '.join(invalid_files)}"
                )
            
            # 添加有效文件到列表
            for file in valid_files:
                item = QListWidgetItem(os.path.basename(file))
                item.setToolTip(file)  # 显示完整路径
                self.file_list.addItem(item)
                self.selected_files.append(file)
            
            if valid_files:
                self.update_file_count()
                self.update_convert_button()
                self.status_label.setText("文件已选择，请选择保存位置")
    
    def update_file_count(self):
        """更新文件计数显示"""
        count = len(self.selected_files)
        self.file_count_label.setText(f"已选择 {count} 个文件")
        self.clear_btn.setEnabled(count > 0)
        self.remove_btn.setEnabled(count > 0)
    
    def clear_file_list(self):
        """清空文件列表"""
        reply = QMessageBox.question(
            self,
            "确认清空",
            "确定要清空所有已选择的文件吗？",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            self.file_list.clear()
            self.selected_files.clear()
            self.update_file_count()
            self.update_convert_button()
            self.status_label.setText("")
    
    def remove_selected_files(self):
        """删除选中的文件"""
        selected_items = self.file_list.selectedItems()
        if not selected_items:
            return
            
        reply = QMessageBox.question(
            self,
            "确认删除",
            f"确定要删除选中的 {len(selected_items)} 个文件吗？",
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            for item in selected_items:
                file_name = item.text()
                full_path = next(
                    (f for f in self.selected_files if f.split('/')[-1] == file_name),
                    None
                )
                if full_path:
                    self.selected_files.remove(full_path)
                row = self.file_list.row(item)
                self.file_list.takeItem(row)
            
            self.update_file_count()
            self.update_convert_button()
    
    def show_context_menu(self, position):
        """显示右键菜单"""
        menu = QMenu()
        delete_action = QAction("删除", self)
        delete_action.triggered.connect(self.remove_selected_files)
        menu.addAction(delete_action)
        
        clear_action = QAction("清空列表", self)
        clear_action.triggered.connect(self.clear_file_list)
        menu.addAction(clear_action)
        
        menu.exec(self.file_list.mapToGlobal(position))
    
    def update_convert_button(self):
        """更新转换按钮状态"""
        self.convert_btn.setEnabled(
            bool(self.selected_files) and bool(self.save_path)
        )
            
    def start_conversion(self):
        if not self.selected_files or not self.save_path:
            return
            
        self.convert_btn.setEnabled(False)
        self.select_btn.setEnabled(False)
        self.save_btn.setEnabled(False)
        self.progress_bar.show()
        self.progress_bar.setValue(0)
        self.status_label.setText("正在转换...")
        
        # 在新线程中执行转换
        threading.Thread(target=self.convert_files, daemon=True).start()
    
    def convert_files(self):
        try:
            total_files = len(self.selected_files)
            for i, input_file in enumerate(self.selected_files):
                # 构建输出文件路径
                filename = os.path.basename(input_file)
                name, _ = os.path.splitext(filename)
                output_file = os.path.join(self.save_path, f"{name}.pdf")
                
                # 更新文件进度
                file_progress = (i / total_files) * 100
                self.signal_emitter.progress_signal.emit(int(file_progress))
                
                # 执行转换，使用闭包来捕获当前文件的索引
                def progress_callback(p, current_index=i):
                    # 计算总体进度：当前文件的进度占比 + 之前文件的进度
                    total_progress = (current_index * 100 + p) / total_files
                    self.signal_emitter.progress_signal.emit(int(total_progress))
                
                # 执行转换
                FileConverter.convert_to_pdf(input_file, output_file, progress_callback)
            
            # 转换完成
            self.signal_emitter.complete_signal.emit()
            
        except Exception as e:
            self.signal_emitter.error_signal.emit(str(e))
    
    def on_progress_update(self, value):
        """处理进度更新信号"""
        self.progress_bar.setValue(value)
    
    def on_error(self, error_message):
        """处理错误信号"""
        # 显示错误对话框
        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Icon.Critical)
        msg.setWindowTitle("转换错误")
        msg.setText("转换过程中发生错误")
        msg.setInformativeText(error_message)
        msg.setStandardButtons(QMessageBox.StandardButton.Ok)
        msg.exec()
        
        # 重置界面
        self.status_label.setText("转换失败")
        self.convert_btn.setEnabled(True)
        self.select_btn.setEnabled(True)
        self.save_btn.setEnabled(True)
        self.progress_bar.setValue(0)
    
    def on_conversion_complete(self):
        """处理转换完成信号"""
        # 显示完成对话框
        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Icon.Information)
        msg.setWindowTitle("转换完成")
        msg.setText("文件转换已完成！")
        msg.setInformativeText(f"转换后的文件已保存到:\n{self.save_path}")
        msg.setStandardButtons(QMessageBox.StandardButton.Ok)
        
        # 添加打开文件夹按钮
        open_button = msg.addButton("打开文件夹", QMessageBox.ButtonRole.ActionRole)
        msg.buttonClicked.connect(
            lambda btn: self.open_save_folder() if btn == open_button else None
        )
        
        msg.exec()
        
        self.status_label.setText("转换完成！")
        self.convert_btn.setEnabled(True)
        self.select_btn.setEnabled(True)
        self.save_btn.setEnabled(True)
        
        # 3秒后重置界面
        QTimer.singleShot(3000, self.reset_interface)
        
    def open_save_folder(self):
        """打开保存文件夹"""
        import os
        import subprocess
        
        if os.path.exists(self.save_path):
            if os.name == 'nt':  # Windows
                os.startfile(self.save_path)
            else:  # Linux/Mac
                subprocess.run(['xdg-open', self.save_path])
        
    def reset_interface(self):
        self.progress_bar.hide()
        self.status_label.setText("")
        self.file_list.clear()
        self.file_count_label.setText("未选择文件")
        self.save_path_label.setText("未选择保存位置")
        self.selected_files = []
        self.save_path = ""
        self.convert_btn.setEnabled(False) 